package com.ys.service.sys.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.ys.entity.sys.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bo.dto.NameValueSelectDto;
import com.bo.util.DateUtil;
import com.ys.config.ImportConfig;
import com.ys.dto.DtreeSqlDto;
import com.ys.entity.flow.YspModel;
import com.ys.enume.sys.YsColEnum;
import com.ys.enume.sys.YsMenuEnum;
import com.ys.mapper.sys.SysMapper;
import com.ys.mapper.sys.YsMenuMapper;
import com.ys.mapper.sys.YsMenuNoMapper;
import com.ys.service.sys.YsMenuService;
import com.ys.vo.R;
import com.ys.vo.W;

@Service("ysMenuService")
public class YsMenuServiceImpl implements YsMenuService {

	@Autowired
	private SysMapper sysMapper;
	
	@Autowired
	private YsMenuMapper ysMenuMapper;
	@Autowired
	private YsMenuNoMapper ysMenuNoMapper;

	@Override
	public DtreeSqlDto dtree() {
		
		DtreeSqlDto.StatusDto status = DtreeSqlDto.StatusDto.init(200, "");

		List<DtreeSqlDto.DataDto> data = new ArrayList<DtreeSqlDto.DataDto>();
		List<YsMenu> listYsMenu = new YsMenu()
				.setOrderby("A.Lev asc, A.SortNo asc")
				.queryList();
		
		// 一级菜单
		for(YsMenu ysMenu1 : listYsMenu) {
			if (ysMenu1.getLev() != YsMenuEnum.Lev.ONE.value) {
				continue;
			}
			String id1 = ysMenu1.getId().toString();
			String title1 = ysMenu1.getName();
			String parentId1 = ysMenu1.getPid().toString();
			
			// 二级菜单
			List<DtreeSqlDto.DataDto> children = new ArrayList<DtreeSqlDto.DataDto>();
			for (YsMenu ysMenu2 : listYsMenu) {
				if (ysMenu2.getPid().longValue() != ysMenu1.getId().longValue()) {
					continue;
				}
				String id2 = ysMenu2.getId().toString();
				String title2 = ysMenu2.getName();
				String parentId2 = ysMenu2.getPid().toString();
				
				// 三级菜单
				List<DtreeSqlDto.DataDto> children1 = new ArrayList<DtreeSqlDto.DataDto>();
				for(YsMenu ysMenu3 : listYsMenu) {
					if (ysMenu3.getPid().longValue() != ysMenu2.getId().longValue()) {
						continue;
					}
					String id3 = ysMenu3.getId().toString();
					String title3 = ysMenu3.getName();
					String parentId3 = ysMenu3.getPid().toString();

					List<DtreeSqlDto.DataDto> children2 = new ArrayList<DtreeSqlDto.DataDto>();
					DtreeSqlDto.DataDto dataDto3 = new DtreeSqlDto.DataDto(id3, title3, parentId3, DtreeSqlDto.DataDto.initCheckArr(null), children2);
					children1.add(dataDto3);
				}
				
				DtreeSqlDto.DataDto dataDto2 = new DtreeSqlDto.DataDto(id2, title2, parentId2, DtreeSqlDto.DataDto.initCheckArr(null), children1);
				children.add(dataDto2);
			}
			
			DtreeSqlDto.DataDto dataDto1 = new DtreeSqlDto.DataDto(id1, title1, parentId1, DtreeSqlDto.DataDto.initCheckArr(null), children);
			data.add(dataDto1);
		}
		return new DtreeSqlDto(status, data);
	}

	@Override
	@Transactional
	public R deleteTrue(Long id) {
		if (id == null) {
			return R.error("ID不能为空");
		}
		
//		// 删除角色-按钮
//		sysMapper.deleteTrueSysRoleButtonByTsDictionaryForModuleId(id);
//		
//		// 删除按钮
//		tsDictionaryForModuleMapper.deleteTrue(id);
		
		return R.ok();
	}
	
	@Override
	public R add(Map<String, Object> params) {
		
		YsMenu entity = JSON.parseObject(JSON.toJSONString(params), YsMenu.class);
		
		String templetType = entity.getTempletType();
		if (templetType.equals(YsMenuEnum.TempletType.LIST.value) || templetType.equals(YsMenuEnum.TempletType.TREE_WITH_LIST.value)) {
			entity.setTempletPath("sys/common/templet_list");
		}
		
		ysMenuMapper.insert(entity);
		return R.ok("操作成功");
	}
	
	@Override
	public R edit(Map<String, Object> params) {

		YsMenu entity = JSON.parseObject(JSON.toJSONString(params), YsMenu.class);
		
		String templetType = entity.getTempletType();
		if (templetType.equals(YsMenuEnum.TempletType.LIST.value) || templetType.equals(YsMenuEnum.TempletType.TREE_WITH_LIST.value)) {
			entity.setTempletPath("sys/common/templet_list");
		}
		
		ysMenuMapper.update(entity);
		return R.ok("操作成功");
	}

	@Override
	public R move(Long id, Long pid) {

		YsMenu entity = new YsMenu().setId(id).queryFirst();
		
		YsMenu pEntity = new YsMenu().setId(pid).queryFirst();
		if (entity.getLev() - 1 != pEntity.getLev()) {
			return R.error("操作失败");
		}
		entity.setPid(pid);
		
		ysMenuMapper.update(entity);
		return R.ok("操作成功");
	}

	@Override
	public String toResort(Model model, Long pid) {
		
		if (pid == null) {
			return W.error(model, "菜单ID不能为空");
		}
		
		List<YsMenu> listYsMenu = new YsMenu().setPid(pid).setOrderby("A.SortNo asc").queryList();
		
		List<ToResortDto.RowDto> rows = new ArrayList<ToResortDto.RowDto>();
		for(YsMenu entity : listYsMenu) {
			Long id = entity.getId();
			String name = entity.getName();
			String code = entity.getDataBaseTable();
			rows.add(new ToResortDto.RowDto(id, name, code));
		}
		
		ToResortDto dto = new ToResortDto(rows);
		model.addAttribute("dto", dto);
		return "sys/ysMenu/toResort";
	}

	@Override
	@Transactional
	public R resortMenu(String rows) {
		JSONArray JA = JSON.parseArray(rows);
		
		for (int i = 0; i < JA.size(); i++) {
			JSONObject JO = JA.getJSONObject(i);
			Long id = JO.getLong("id");
			Integer sortNo = i + 1;
			sysMapper.updateYsMenuOfSortNo(id, sortNo);
		}
		return R.ok();
	}

	@Override
	@Transactional
	public R resortCol(String rows, Integer sortType) {
		JSONArray JA = JSON.parseArray(rows);
		
		for (int i = 0; i < JA.size(); i++) {
			JSONObject JO = JA.getJSONObject(i);
			Long id = JO.getLong("id");
			Integer sortNo = i + 1;
			
			if(sortType == null || sortType == 1) {
				sysMapper.updateSortNoById(new YsCol().generateTableAllName(), id, sortNo);
			} else if(sortType == 2) {
				sysMapper.updateYsColOfImportSortNo(id, sortNo);
			} else if(sortType == 3) {
				sysMapper.updateSortNoById(new YsGridCol().generateTableAllName(), id, sortNo);
			} else if(sortType == 4) {
				sysMapper.updateSortNoById(new YsGridButton().generateTableAllName(), id, sortNo);
			} else if(sortType == 5) {
				sysMapper.updateSortNoById(new YsButton().generateTableAllName(), id, sortNo);
			} else if(sortType == 6) {
				sysMapper.updateSortNoById(new YsRowClickGridCol().generateTableAllName(), id, sortNo);
			}
		}
		return R.ok();
	}

	@Override
	public String toSettingBase(Model model, Long id) {
		if (id == null) {
			return W.error(model, "ID不能为空");
		}
		
		YsMenu entity = new YsMenu().setId(id).queryFirst();
		
		String name = entity.getName();
		String nameShiroAuth = entity.getNameShiroAuth();
		
		String templetType = entity.getTempletType();
		String pathGridRequest = entity.getPathGridRequest();
		String pathGridEditRequest = entity.getPathGridEditRequest();
		String pathGridExportRequest = entity.getPathGridExportRequest();
		String pathCommitAdd = entity.getPathCommitAdd();
		String pathCommitEdit = entity.getPathCommitEdit();
		String pathCommitDelete = entity.getPathCommitDelete();
		String pathFlowPass = entity.getPathFlowPass();
		String pathFlowRefuse = entity.getPathFlowRefuse();
		String pathFlowInit = entity.getPathFlowInit();
		
		String dataBaseTable = entity.getDataBaseTable();
		String pathSelfDefine = entity.getTempletPath();
		pathGridRequest = pathGridRequest == null || pathGridRequest.length() == 0 ? "/api/inter/" + com.ys.util.StringUtil.parseTableName(dataBaseTable) + "/search" : pathGridRequest;
		pathGridEditRequest = pathGridEditRequest == null || pathGridEditRequest.length() == 0 ? "/api/inter/common/editOnTable?menuId=" + entity.getId() : pathGridEditRequest;
		pathGridExportRequest = pathGridExportRequest == null || pathGridExportRequest.length() == 0 ? "/api/inter/" + com.ys.util.StringUtil.parseTableName(dataBaseTable) + "/export" : pathGridExportRequest;

		ysMenuMapper.update(entity);

		
		List<NameValueSelectDto> templetTypeArr = new ArrayList<NameValueSelectDto>();
		for (YsMenuEnum.TempletType e : YsMenuEnum.TempletType.values()) {
			templetTypeArr.add(new NameValueSelectDto(e.name, e.value.toString(), e.value.equals(templetType)));
		}
		
		// 流程数组
		Long flowModelId = entity.getFlowModelId();
		List<NameValueSelectDto> flowModelArr = new ArrayList<NameValueSelectDto>();
		List<YspModel> listYspModel = new YspModel().queryList();
		{
			flowModelArr.add(new NameValueSelectDto("暂未设置", "0", flowModelId.longValue() == 0L));
		}
		for(YspModel yspModel : listYspModel) {
			String name2 = yspModel.getName() + "(" + yspModel.getCode() + ")";
			String value = yspModel.getId().toString();
			boolean isSelected = flowModelId != null && flowModelId.longValue() == yspModel.getId().longValue() ? true : false;
			flowModelArr.add(new NameValueSelectDto(name2, value, isSelected));
		}
		
		YsMenuNo ysMenuNo = new YsMenuNo().setMenuId(id).queryFirst();
		String preCode = null; // 单号头
		String connectCode = null; // 连接符
		Integer startNo = null; // 起始号
		if (ysMenuNo != null) {
			preCode = ysMenuNo.getPreCode();
			connectCode = ysMenuNo.getConnectCode();
			startNo = ysMenuNo.getStartNo();
		}
		
		// 子列表数组
		Long gridId = entity.getGridId();
		List<NameValueSelectDto> gridArr = new ArrayList<NameValueSelectDto>();
		List<YsGrid> listYsGrid = new YsGrid().queryList();
		{
			gridArr.add(new NameValueSelectDto("暂未设置", "0", gridId.longValue() == 0L));
		}
		for(YsGrid ysGrid : listYsGrid) {
			String name2 = ysGrid.getName() + "(ID:" + ysGrid.getId() + ")";
			String value = ysGrid.getId().toString();
			boolean isSelected = gridId != null && gridId.longValue() == ysGrid.getId().longValue() ? true : false;
			gridArr.add(new NameValueSelectDto(name2, value, isSelected));
		}
		
		// 行单击列表数组
		Long rowClickGridId = entity.getRowClickGridId();
		List<NameValueSelectDto> rowClickGridArr = new ArrayList<NameValueSelectDto>();
		List<YsRowClickGrid> listYsRowClickGrid = new YsRowClickGrid().queryList();
		{
			rowClickGridArr.add(new NameValueSelectDto("暂未设置", "0", rowClickGridId.longValue() == 0L));
		}
		for(YsRowClickGrid ysRowClickGrid : listYsRowClickGrid) {
			String name2 = ysRowClickGrid.getName() + "(ID:" + ysRowClickGrid.getId() + ")";
			String value = ysRowClickGrid.getId().toString();
			boolean isSelected = rowClickGridId != null && rowClickGridId.longValue() == ysRowClickGrid.getId().longValue() ? true : false;
			rowClickGridArr.add(new NameValueSelectDto(name2, value, isSelected));
		}
		
		
		ToSettingDto dto = new ToSettingDto(id, name, nameShiroAuth, templetTypeArr, pathSelfDefine, pathGridRequest, pathGridEditRequest, pathGridExportRequest, pathCommitAdd, pathCommitEdit, pathCommitDelete,
				flowModelArr, pathFlowPass, pathFlowRefuse, pathFlowInit,
				preCode, connectCode, startNo, gridArr, rowClickGridArr);
		model.addAttribute("dto", dto);
		return "sys/ysMenu/toSettingBase";
	}

	@Override
	public R settingBase(Long id,
			String nameShiroAuth,
			String templetType,
			String pathSelfDefine,
			String pathGridRequest, String pathGridEditRequest, String pathGridExportRequest,
			String pathCommitAdd, String pathCommitEdit, String pathCommitDelete,
			Long flowModelId, String pathFlowPass, String pathFlowRefuse, String pathFlowInit,
			String preCode, String connectCode, Integer startNo,
			Long gridId,
			Long rowClickGridId) {
		
		YsMenu entity = new YsMenu().setId(id).queryFirst();
		if (entity == null) {
			return R.error();
		}
		
		// 自定义时，必须配置相关地址
		else if (YsMenuEnum.TempletType.SELF_DEFINE.value.equals(templetType)) {
			if (pathSelfDefine == null || pathSelfDefine.length() == 0) {
				return R.error("请填写自定义地址");
			}
		}
		
		// 模板地址
		String templetPath = "";
		if (YsMenuEnum.TempletType.LIST.value.equals(templetType) || YsMenuEnum.TempletType.TREE_WITH_LIST.value.equals(templetType)) {
			templetPath = "sys/common/templet_list";
		}
		else if (YsMenuEnum.TempletType.SELF_DEFINE.value.equals(templetType)) {
			templetPath = pathSelfDefine;
		}
		
		// 验证单号前缀唯一
		if (preCode != null && preCode.length() > 0) {
			Integer num = new YsMenuNo().setPreCode(preCode).where("A.MenuId != " + id).count();
			if (num > 0) {
				return R.error("已存在相同单号头");
			}
		} else {
			preCode = "";
		}

		entity
			.setNameShiroAuth(nameShiroAuth)
			.setTempletType(templetType)
			.setTempletPath(templetPath)
			.setPathGridRequest(pathGridRequest)
			.setPathGridEditRequest(pathGridEditRequest)
			.setPathGridExportRequest(pathGridExportRequest)
			.setPathCommitAdd(pathCommitAdd)
			.setPathCommitEdit(pathCommitEdit)
			.setPathCommitDelete(pathCommitDelete)
			.setFlowModelId(flowModelId)
			.setPathFlowPass(pathFlowPass)
			.setPathFlowRefuse(pathFlowRefuse)
			.setPathFlowInit(pathFlowInit)
			.setGridId(gridId)
			.setRowClickGridId(rowClickGridId);
		ysMenuMapper.update(entity);
		
		if (startNo != null && startNo > 0) {
			YsMenuNo ysMenuNo = new YsMenuNo().setMenuId(id).queryFirst();
			if (ysMenuNo == null) {
				Long menuId = id;
				Integer currentNo = startNo;
				String currentDay = DateUtil.getYYYY_MM_DD(new Date());
				ysMenuNo = YsMenuNo.ysMenuNo(menuId, preCode, connectCode, startNo, currentNo, currentDay, 1);
				ysMenuNoMapper.insert(ysMenuNo);
			} else {
				ysMenuNo.setPreCode(preCode)
					.setConnectCode(connectCode)
					.setStartNo(startNo)
					.setCurrentNo(startNo);
				ysMenuNoMapper.update(ysMenuNo);
			}
		}
		return R.ok("操作成功");
	}

	@Override
	public R importConfig(Long menuId) {
		if (menuId == null) {
			return R.error("菜单ID不能为空");
		} else if (!ImportConfig.ID_FILENAME_MAP.containsKey(menuId)) {
			return R.error("该菜单尚未配置生成路径");
		}
		
		List<YsCol> listYsCol = new YsCol().setMenuId(menuId).setImportState(YsColEnum.ImportState.YES.value)
				.setOrderby("A.ImportSortNo asc")
				.queryList();
		JSONObject nameValMap = new JSONObject();
		for(YsCol entity : listYsCol) {
			nameValMap.put(entity.getName(), entity.getCode());
		}
		
		String fileName = ImportConfig.ID_FILENAME_MAP.get(menuId) + ".xlsx";
		ImportConfigDto dto = new ImportConfigDto(menuId, nameValMap, fileName);
		return R.ok(dto);
	}
}
